var camera;
var mouseDown = false;

var lightPos = [0, 100, 0];

function init(){
	QtInit(function(){
		SceneManager.createLoader(function(){
		});
		TextureManager.createLoader(function(){
		});
		camera = SceneManager.createMainCamera();
		camera.setProjection();
		camera.setCamera([10, 10, 0], [0, 5, 0], [0, 1, 0]);
		camera.disable();
		light = SceneManager.createLight("main_light", {
			"type" : "DIRECT",
			"direction" : [0, 400, 80],
			"color" : [1, 1, 1, 1],
			"power" : 1
		});
		light1 = SceneManager.createLight("light1", {
			"type" : "DIRECT",
			"direction" : [0, 1, 0.4],
			"color" : [1, 1, 1, 0.5],
		});
		light2 = SceneManager.createLight("light2", {
			"type" : "POINT",
			"position" : lightPos,
			"color" : [1, 1, 1, 1],
			"attenuation" : 0.01
		});
		
		
		SceneManager.loadModel("Sponza", "media/model/Sponza2.o3dtgz", "main_camera", function(transform){
			//you can not directly bind it to the client root, because the transform tree root of camera's
			//render node is the transform camera
			transform.scale(0.1, 0.1, 0.1);
			SceneManager.listPrimitives();
			
			MaterialManager.loadFxFile("phong", "media/material/phong.json", function(phong){
				var primitives = SceneManager.getTransformPrimitiveMap("Sponza");
				for(var i = 0; i < primitives.length; i++){
					var material = SceneManager.getPrimitive(primitives[i]).material;
					if(isset(material)){
						material = MaterialManager.createFromImportedMaterial(material, "phong");
						SceneManager.getPrimitive(primitives[i]).material = material;
					}else{
						SceneManager.getPrimitive(primitives[i]).material = phong;
					}
				}
				
				var replace = {
					"bricks" : "media/texture/spnza_bricks_a_ddn.jpg",
					"arch" : "media/texture/sponza_arch_ddn.jpg",
					"column_a" : "media/texture/sponza_column_a_ddn.jpg",
					"column_b" : "media/texture/sponza_column_b_ddn.jpg",
					"column_c" : "media/texture/sponza_column_c_ddn.jpg",
					"thorn" : "media/texture/sponza_thorn_ddn.jpg",
					"lion" : "media/texture/lion_ddn.jpg",
					"background" : "media/texture/background_ddn.jpg"
				}
				var opCount = 0;
				for(var materialName in replace){
					var option = MaterialManager.getOption(materialName).Texture.normalSampler;
					option.src = replace[materialName];
					opCount++;
					TextureManager.createSampler(option.src, option, function(sampler){
						opCount--;
						if(opCount == 0){
							for (var materialName in replace) {
								MaterialManager.updateParam(materialName, "hasNormalSampler", 1);
								MaterialManager.updateTexture(materialName, "normalSampler", TextureManager.getSampler(replace[materialName]), replace[materialName]);
//								MaterialManager.updateParam(materialName, "shininess", 0);
							}
						}
					});
				}

				light.createShadowMap("main_camera");
				
//				light.bindToTransform("Sponza");
				
				SceneManager.createSkybox([1, 1, 1, 1]);
				DeferredShading.createGBuffer("gbuffer", "main_camera");
				var shadow = DeferredShading.calShadowMap(light);
				light.shadow = PostProcessing.gaussEdge(light.shadow, 5);
				
				DeferredShading.addLight(light);
//				DeferredShading.addLight(light1);
				DeferredShading.addLight(light2);
//				var ssaoMap = DeferredShading.createSSAO();
//				ssaoMap = PostProcessing.gauss(ssaoMap, 1, true);
//				PostProcessing.compound(ssaoMap, DeferredShading.getFinalRenderTarget(), PostProcessing.compoundType.MUL true);
				var extract = PostProcessing.extract(DeferredShading.getFinalRenderTarget(), 0.8);
				extract = PostProcessing.gray(extract);
				extract = PostProcessing.gauss(extract, 5);
				PostProcessing.compound(extract, DeferredShading.getFinalRenderTarget(), PostProcessing.compoundType.ADD, true);
			});
		});
		
		SceneManager.addEventListener("mousedown", mouseDownEvent);
		SceneManager.addEventListener("keydown", keyDownEvent);
		SceneManager.addEventListener("mousemove", mouseMoveEvent);
		SceneManager.addEventListener("mouseup", mouseUpEvent);
	})
}

function mouseDownEvent(e)
{
	mouseDown = true;
	oldPositionX = e.x;
	oldPositionY = e.y;
}

function mouseMoveEvent(e)
{
	if(mouseDown){
		var cameraInfo = camera.getCameraInfo();
		var aroundPosition = o3djs.math.copyVector(cameraInfo.eye);

		var vector = o3djs.math.subVector(cameraInfo.target, cameraInfo.eye);
		var vector2 = o3djs.math.copyVector(vector);
		vector2[1] = vector2[1] + 1;
		aroundXAxis = o3djs.math.cross(vector, vector2);
		$("#debug").html(dumpVector(aroundXAxis));
		camera.moveTargetAround({
			aroundAxis : [0, 1, 0],
			aroundPos : aroundPosition,
			step : (e.x - oldPositionX) / 1000
		})
		camera.moveTargetAround({
			aroundAxis : aroundXAxis,
			aroundPos : aroundPosition,
			step : (e.y - oldPositionY) / 1000
		})
		oldPositionX = e.x
		oldPositionY = e.y
		
		DeferredShading.updateGBuffer();
	}
	
}

function mouseUpEvent(e)
{
	mouseDown = false;
}


function keyDownEvent(e)
{
	var cameraInfo = camera.getCameraInfo();
	var vector = o3djs.math.subVector(cameraInfo.target, cameraInfo.eye);
	//vector[1] = 0;
	switch(e.keyCode){
		//key "W"
		case 87:
			camera.moveAlong({
				eyeAlong : vector,
				targetAlong : vector,
				step : 0.6
			})
			break;
		//key "S"
		case 83:
			vector = o3djs.math.subVector([0, 0, 0], vector);
			camera.moveAlong({
				eyeAlong : vector,
				targetAlong : vector,
				step : 0.6
			})
			break
		//key "A"
		case 65:
			vector = o3djs.math.subVector([0, 0, 0], o3djs.math.cross(vector, [0, 1, 0]));
			camera.moveAlong({
				eyeAlong : vector,
				targetAlong : vector,
				step : 0.3
			})
			break
		//key "D"
		case 68:
			vector = o3djs.math.cross(vector, [0, 1, 0]);
			camera.moveAlong({
				eyeAlong : vector,
				targetAlong : vector,
				step : 0.3
			})
			break;
	}
	DeferredShading.updateGBuffer();
}
